#include"tcpsocket.hpp"
#include<signal.h>
#include<cstdlib>
#include<string>
#include<algorithm>
#include"cala.hpp"
using namespace std;

//多进程
void create_worker(TcpSocket &sock){
    pid_t pid=fork();
    if(pid<0){
        sock.Close();
        return;
    }
    else if(pid==0){//子进程只负责与指定客户端通信
        while(1){
        //收发数据
        string body;
        bool ret=sock.Recv(&body);
        if(ret==false){
            sock.Close();
            continue;
        }
        cout<<"client say:"<<body<<endl;
        body.clear();
        cout<<"server say:";
        fflush(stdout);
        cin>>body;
        ret=sock.Send(body);
        if(ret==false){
            break;
            }
        }
        //子进程循环完毕就退出，不能让子进程继续运行
        sock.Close();//子进程关闭套接字
        exit(-1);
    }
    //父子进程数据独有，因此父进程关闭，并不影响子进程
    //并且父进程不关闭反而会造成资源泄漏，因为父进程不与客户端通信,只获取新建连接
    sock.Close();//父进程关闭套接字
}
void recv_req(TcpSocket &sock){
    string line=sock.getline();
    cout<<"req line"<<line<<endl;
    uint64_t content_len=0;
    while(1){
        string line=sock.getline();
        if(line=="\n"||line=="\r\n"){
            break;
        }
        //a\r\n
        //line.erase(line.size()-2);
        //cout<<"req header "<<line<<endl;
        //Content-Length:xxx
        string key="Content-Length";
        size_t pos=line.find(key);
        if(pos!=string::npos){
            //Content-Length: 12
            string len=line.substr(key.size()+2);
            content_len=atoi(len.c_str());
        }
    }
    printf("content_len:%d\n",content_len);
    if(content_len!=0){
        string body;
        sock.Recv(&body,content_len);
        cout<<"req body:"<<body<<endl;
    }
}
void response(TcpSocket &sock){
    string body;
    body="<html>";
    body+="<head>";
    body+="<meta charset='utf8'>";
    body+="</head>";
    body+="<body>";
    body+="<h1> hello </h1>";
    body+="</body>";
    body+="</html>";
    //sock.Send("HTTP/1.1 200 OK\r\n");
    sock.Send("HTTP/1.1 302 OK\r\n");
    string content_length="Content-Length: "+to_string(body.size())+"\r\n";
    sock.Send(content_length);
    sock.Send("Content-Type: text/html\r\n");
    sock.Send("Location: http://www.baidu.com\r\n");
    sock.Send("\r\n");
    sock.Send(body);
}
void *thread_entry(void *arg){
    //TcpSocket sock((int)arg);
    TcpSocket sock((long)arg);
    recv_req(sock);
    //业务处理
    response(sock);
    sock.Close();
    return NULL;
    printf("线程结束\n");
}
//多线程
void create_thread(TcpSocket &sock){//线程描述符不能关闭，否则影响进程内的其它线程
    pthread_t tid;
    int ret=pthread_create(&tid,NULL,thread_entry,(void*)sock.Fd());
    if(ret!=0){
        cout<<"create thread error"<<endl;
        sock.Close();
        return;
    }
    pthread_detach(tid);//分离线程-退出自动释放所有资源,不需要被等待
}
#define CHECK_RET(r) if((r) == false){return -1;}
int main(int argc,char *argv[]){
    if(argc!=3){
        cout<<"usage:./tcp_srv 9000\n";
        return -1;
    }
    //显式忽略SIGCHLD信号处理，当子进程退出后自动释放资源
    signal(SIGCHLD,SIG_IGN);
    string ip="0.0.0.0";
    uint16_t port=atoi(argv[2]);
    TcpSocket lsn_sock;
    //创建套接字
    CHECK_RET(lsn_sock.Socket());
    //绑定地址信息
    CHECK_RET(lsn_sock.Bind(ip,port));
    //开始监听
    CHECK_RET(lsn_sock.Listen());
    while(1){
    //获取新建连接
    TcpSocket new_sock=lsn_sock.Accept();//这是个阻塞接口
    if(new_sock.Available()==false){
        continue;
    }
    //create_worker(new_sock);
    create_thread(new_sock);
    }
    //关闭套接字
    //lsn_sock.Close();
    return 0;
}